import { Text, View, ProgressViewIOS, StyleSheet, TouchableOpacity } from 'react-native'
import React, { Component, useRef, useState, useEffect } from 'react'
import { WebView } from 'react-native-webview';
import { connect } from 'react-redux'
import { ethers } from "ethers";
import { asyncGetBrowserSearchLogs } from "../../redux/features/dappSlice"
import { Button, Modal, Toast, WhiteSpace, WingBlank } from '@ant-design/react-native'
import { ProgressBar } from '@react-native-community/progress-bar-android';
import { pTx } from "../../utils/dimensions"
import { IconFill, IconOutline } from "@ant-design/icons-react-native";
import { useRealm, useQuery } from '@realm/react'
import { schemaName } from "../../realm"
import NetworkList from "../../utils/NetworkList"
import SendTransaction from "../../components/sendTransaction"
import PersonalSign from "../../components/personalSign"

const mapState = state => {
    return {
        wallet: state.wallet,
        network: state.network
    }
};

const Web3View = ({ route, navigation, asyncGetBrowserSearchLogs }) => {
    const realm = useRealm();
    const wallet = useQuery(schemaName.Wallet, wallet => {
        return wallet.filtered('current = true');
    })[0];
    const rpcURL = NetworkList.find(item => item.chainId == wallet.chainId).rpcUrl
    const provider = new ethers.providers.JsonRpcProvider(rpcURL);
    const webviewRef = useRef(null);
    const sendTransactionRefs = useRef(null)
    const personalSignRefs = useRef(null)
    const [backButtonEnabled, setBackButtonEnabled] = useState(null)
    const [progress, setProgress] = useState()
    const [url, setUrl] = useState()
    const injectedJavaScript = `
window.ethereum = {};
window.ethereum.isMetaMask = true;
window.ethereum.isConnected = function() {
  console.log('-----------连接成功后调用---------')
  return true
};
window.ethereum.wallet = {};
window.ethereum.wallet.address = ${wallet.address};
window.ethereum.selectedAddress = ${wallet.address};
window.ethereum.request = function(args = {}) {
//   console.log('---------Dapp交互触发该事件-----------')
  const { method, params } = args
  return window.ethereum.send(method, params)
};
window.ethereum.send = function(method, params) {
   let time = new Date().getTime()+''+Math.floor(Math.random() * 900 + 100)
    console.log('---------send-----------', method,time,params)
  return new Promise(function(resolve, reject) {
    window.ReactNativeWebView.postMessage(JSON.stringify({
        type: 'bsc',
        payload: { 
            method: method,
            params: params,
            time:time
        }
    }));
    document.addEventListener("message", function(event) {
      /**
      * wallet端主动调用postMessage触发该事件
      * 将webviewRef.current.postMessage回调的event.data作为Promise的值返回
      */
      const data = JSON.parse(event.data) || {}
      if (data.type === 'ethereum' && data.payload.id === method  && data.payload.time === time) {
          if (data.payload.error) {
            //console.log("error", method)
              reject(data.payload.error);
          } else {
            // console.log(data.payload.result, '---------'+data.payload.id+'-----------',time)
              resolve(data.payload.result);
          }
      }
    }, {  passive:true,
          capture:true,
        //   once: true 
     });
  });
};
window.ethereum.on = function(event, callback){}
`;

    useEffect(() => {
        navigation.setOptions({
            header: ({ options }) => (
                <View style={styles.NavBar}>
                    <View style={styles.onPressLeft}>
                        <TouchableOpacity onPress={() => backButtonEnabled ? webviewRef.current.goBack() : navigation.goBack()}>
                            <IconOutline style={styles.NavBarIcon} name="left" />
                        </TouchableOpacity>
                        {backButtonEnabled ?
                            <TouchableOpacity onPress={() => navigation.goBack()}>
                                <IconOutline style={[styles.NavBarIcon, { paddingLeft: 0 }]} name="close" />
                            </TouchableOpacity>
                            : ""}
                    </View>
                    <Text style={styles.NavBarTitle} ellipsizeMode={'tail'} numberOfLines={1}>
                        {options.headerTitle || route.params.title}
                    </Text>
                    <View style={styles.onPressRight}>
                        <IconOutline style={styles.NavBarIcon} name="ellipsis" />
                    </View>
                </View>
            ),
        });
    }, [navigation, backButtonEnabled]);
    const getEth_getTransactionReceipt = (params) => {
        return new Promise(function (resolve, reject) {
            setTimeout(async () => {
                result = await provider.send('eth_getTransactionReceipt', params)
                resolve(result)
            }, 5000)
        })
    }
    const handleWebViewMessage = async function (event) {

        /**
        * Dapp端交互调用window.ethereum.request时触发
        * 根据window.ReactNativeWebView.postMessage传递的不同参数，返回对应的结果
        */
        const { data } = event.nativeEvent;
        const { type, payload = {} } = JSON.parse(data) || {};
        const { method, params, time } = payload;
        // console.log(method, params, time)
        // console.log(await provider.send({ method: "subtract", "params": [42, 23], "id": 1 }))
        // return
        let result;
        try {
            switch (method) {
                case 'eth_accounts':
                    result = [wallet.address];
                    break;
                case 'eth_requestAccounts':
                    result = [wallet.address];
                    break;
                case 'eth_blockNumber':
                    result = await provider.getBlockNumber()
                    break;
                case 'eth_call':
                    // console.log(await provider.send("eth_call", params))
                    result = await provider.send("eth_call", params);
                    break;
                case 'eth_chainId':
                    result = await provider.send("eth_chainId");
                    break;
                case 'eth_estimateGas':
                    result = await provider.estimateGas(params)
                    break;
                case 'eth_feeHistory':
                    result = await provider.send('eth_feeHistory', params)
                    break;
                case 'eth_gasPrice':
                    result = await provider.getGasPrice()
                    break;
                case 'eth_getAccount':
                    result = await provider.send("eth_getAccount", [
                        params[0],
                        params[1]
                    ]);
                    break;
                case 'eth_getBalance':
                    result = (await provider.getBalance(params[0], params[1])).toString()
                    break;

                case 'net_version':
                    result = 56
                    break;
                case 'net_listening':
                    result = true
                    break;
                case 'wallet_switchEthereumChain':
                    break;
                case 'personal_sign':
                    personalSignRefs.current.show(data)
                    break;
                case 'eth_getBlockByNumber':
                    const getBlock = await provider.getBlock(params[0], params[1])
                    getBlock.baseFeePerGas = getBlock.baseFeePerGas.toString()
                    result = getBlock
                    break;

                case 'eth_sendTransaction':
                    sendTransactionRefs.current.show(data)
                    break;
                case 'eth_subscribe':
                    result = await provider('eth_subscribe', params)
                    break;
                case 'eth_getTransactionByHash':
                    result = await provider.send("eth_getTransactionByHash", params)
                    break;
                case 'eth_getTransactionReceipt':
                    result = await getEth_getTransactionReceipt(params)
                    console.log(result, "0000000000000000--------")
                    break;

                // ... Add other methods as needed
                default:
                    throw new Error("Unsupported method: " + method);
            }
            if (result) {
                console.log(method,
                    result)
                webviewRef.current.postMessage(JSON.stringify({
                    type: 'ethereum',
                    payload: {
                        id: method,
                        time,
                        result: result,
                    },
                }));
            }

        } catch (error) {
            // console.log(error)
            console.log("error", result, method)
            webviewRef.current.postMessage(JSON.stringify({
                type: 'ethereum',
                payload: {
                    id: method,
                    time,
                    error
                },
            }));
        }

    };

    const updatePostMessage = (payload) => {
        // console.log(payload, "---------------------------")
        webviewRef.current.postMessage(JSON.stringify({
            type: 'ethereum',
            payload
        }));
    }


    onNavigationStateChange = (navState) => {
        // console.log(navState.canGoBack)
        setBackButtonEnabled(navState.canGoBack);
    };
    return (
        <>
            {progress !== 1 && <ProgressBar
                styleAttr="Horizontal"
                indeterminate={false}
                progress={progress}
                style={styles.styleAttr}
                color="rgba(51, 225, 144, 1)"
            />}

            <WebView
                ref={webviewRef}
                source={{ uri: route.params.url }}
                style={{ flex: 1 }}
                javaScriptEnabled={true}
                onMessage={handleWebViewMessage}
                injectedJavaScriptBeforeContentLoaded={injectedJavaScript}
                onLoadProgress={({ nativeEvent }) => setProgress(
                    nativeEvent.progress
                )}
                onLoadStart={(event) => {
                    navigation.setOptions({
                        headerTitle: event.nativeEvent.title,
                    });
                    if (!url) setUrl(event.nativeEvent.url)
                }}
                onLoadEnd={(event) => {
                    var domain = event.nativeEvent.url.split('/')
                    var icon = ""
                    navigation.setOptions({
                        headerTitle: event.nativeEvent.title,
                    });
                    if (domain[2]) {
                        icon = domain[0] + "//" + domain[2] + "/favicon.ico"
                    }
                    if (url) realm.write(() => {
                        const urlIndex = realm.objects(schemaName.BrowserSearchLogs).filtered(`url == '${route.params.url}'`)
                        if (urlIndex.length == 0) return
                        realm.create(schemaName.BrowserSearchLogs, {
                            ...urlIndex[0],
                            title: event.nativeEvent.title,
                            icon
                        }, true);
                    })
                }}
                onNavigationStateChange={onNavigationStateChange}
            />
            <SendTransaction ref={sendTransactionRefs} updateParentMessage={updatePostMessage.bind(this)} />
            <PersonalSign ref={personalSignRefs} updateParentMessage={updatePostMessage.bind(this)} />
        </>
    )
}
const mapDispatchToProps = {
    asyncGetBrowserSearchLogs
}
export default connect(mapState, mapDispatchToProps)(Web3View)

const styles = StyleSheet.create({
    NavBar: {
        position: "relative",
        flexDirection: 'row',
        alignItems: "center",
        justifyContent: "space-between"
    },
    NavBarTitle: {
        flex: 1,
        fontSize: pTx(16),
        color: "#0A0C14",
        textAlign: "center"
    },
    onPressLeft: {
        flexDirection: 'row',
        alignItems: "center",
        justifyContent: "space-between",
        width: pTx(60),
    },
    NavBarIcon: {
        paddingHorizontal: pTx(10),
        paddingVertical: pTx(10),
        textAlign: "right",
        fontSize: pTx(24),
        color: "#0A0C14",
        fontWeight: "500"
    },
    onPressRight: {
        width: pTx(60),
    },
    styleAttr: {
        position: "absolute",
        zIndex: 9,
        top: 0,
        padding: 0,
        margin: 0,
        height: 3,
    }
})